﻿using Microsoft.CSharp;
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Reflection;
using System.Text;

namespace Sources
{
	/// <summary>
	/// Helper to handle the artefacts cs file
	/// </summary>
	public static class Helper
	{
		/// <summary>
		/// Method to get all Fields from loaded cs file
		/// </summary>
		public static MethodInfo GetFields;
		/// <summary>
		/// Method to get all ContentTypes from loaded cs file
		/// </summary>
		public static MethodInfo GetContentTypes;
		/// <summary>
		/// Method to get all Lists from loaded cs file
		/// </summary>
		public static MethodInfo GetLists;
		/// <summary>
		/// Load the cs file
		/// </summary>
		/// <param name="artefactFile">Filepath containing the artefacts</param>
		public static void LoadArtefacts(string artefactFile)
		{
			var csc = new CSharpCodeProvider(new Dictionary<string, string> { { "CompilerVersion", "v4.0" } });
			var cp = new CompilerParameters()
			{
				GenerateExecutable = false,
				OutputAssembly = "Artefacts.compiled.dll",
				GenerateInMemory = true
			};

			cp.ReferencedAssemblies.Add("mscorlib.dll");
			cp.ReferencedAssemblies.Add("System.dll");
			cp.ReferencedAssemblies.Add("Sources.dll");

			var code = System.IO.File.ReadAllText(artefactFile);

			var results = csc.CompileAssemblyFromSource(cp, code);

			if (results.Errors.HasErrors)
			{
				var sb = new StringBuilder();

				foreach (CompilerError error in results.Errors)
				{
					sb.AppendLine($"Error ({error.ErrorNumber}): {error.ErrorText}");
				}

				throw new InvalidOperationException(sb.ToString());
			}

			var assembly = results.CompiledAssembly;
			var program = assembly.GetType("DeploySources.Artefacts");
			GetFields = program.GetMethod("GetFields");
			GetContentTypes = program.GetMethod("GetContentTypes");
			GetLists = program.GetMethod("GetLists");
		}
	}
}
